<!DOCTYPE html>
<!-- saved from url=(0044)http://mybatis.org/spring/zh/sqlsession.html -->
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="zh" lang="zh"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="author" content="Hunter Presnall">
    <meta name="author" content="Eduardo Macarron">
    <meta name="author" content="Nan Lei">
    <meta name="Date-Revision-yyyymmdd" content="20200309">
    <meta http-equiv="Content-Language" content="zh">
    <title>mybatis-spring – MyBatis-Spring | 使用 SqlSession</title>
    <link rel="stylesheet" href="./mybatis-spring – MyBatis-Spring _ 使用 SqlSession_files/apache-maven-fluido-1.7.min.css">
    <link rel="stylesheet" href="./mybatis-spring – MyBatis-Spring _ 使用 SqlSession_files/site.css">
    <link rel="stylesheet" href="./mybatis-spring – MyBatis-Spring _ 使用 SqlSession_files/print.css" media="print">
    <script type="text/javascript" src="./mybatis-spring – MyBatis-Spring _ 使用 SqlSession_files/apache-maven-fluido-1.7.min.js.下载"></script>
  </head>
  <body class="topBarDisabled">
    <div class="container-fluid">
      <div id="banner">
        <div class="pull-left"><div id="bannerLeft"><h2>mybatis-spring</h2>
</div>
</div>
        <div class="pull-right"><a href="http://mybatis.org/" id="bannerRight" title="MyBatis logo"><img src="./mybatis-spring – MyBatis-Spring _ 使用 SqlSession_files/mybatis-logo.png" alt="MyBatis logo"></a></div>
        <div class="clear"><hr></div>
      </div>

      <div id="breadcrumbs">
        <ul class="breadcrumb">
        <li id="publishDate">最近更新: 09 三月 2020<span class="divider">|</span>
</li>
          <li id="projectVersion">版本: 2.0.4</li>
        </ul>
      </div>
      <div class="row-fluid">
        <div id="leftColumn" class="span2">
          <div class="well sidebar-nav">
    <ul class="nav nav-list">
      <li class="nav-header">参考文档</li>
    <li><a href="http://mybatis.org/spring/zh/index.html" title="简介"><span class="none"></span>简介</a></li>
    <li><a href="http://mybatis.org/spring/zh/getting-started.html" title="入门"><span class="none"></span>入门</a></li>
    <li><a href="http://mybatis.org/spring/zh/factorybean.html" title="SqlSessionFactoryBean"><span class="none"></span>SqlSessionFactoryBean</a></li>
    <li><a href="http://mybatis.org/spring/zh/transactions.html" title="事务"><span class="icon-chevron-right"></span>事务</a></li>
    <li class="active"><a href="http://mybatis.org/spring/zh/sqlsession.html#"><span class="icon-chevron-down"></span>使用 SqlSession</a>
    <ul class="nav nav-list">
    <li><a href="http://mybatis.org/spring/zh/sqlsession.html#SqlSessionTemplate" title="SqlSessionTemplate"><span class="none"></span>SqlSessionTemplate</a></li>
    <li><a href="http://mybatis.org/spring/zh/sqlsession.html#SqlSessionDaoSupport" title="SqlSessionDaoSupport"><span class="none"></span>SqlSessionDaoSupport</a></li>
    </ul>
</li>
    <li><a href="http://mybatis.org/spring/zh/mappers.html" title="注入映射器"><span class="icon-chevron-right"></span>注入映射器</a></li>
    <li><a href="http://mybatis.org/spring/zh/boot.html" title="使用 Spring Boot"><span class="none"></span>使用 Spring Boot</a></li>
    <li><a href="http://mybatis.org/spring/zh/using-api.html" title="使用 MyBatis API"><span class="none"></span>使用 MyBatis API</a></li>
    <li><a href="http://mybatis.org/spring/zh/batch.html" title="使用 Spring Batch"><span class="none"></span>使用 Spring Batch</a></li>
    <li><a href="http://mybatis.org/spring/zh/sample.html" title="示例代码"><span class="none"></span>示例代码</a></li>
      <li class="nav-header">项目文档</li>
    <li><a href="http://mybatis.org/spring/zh/project-info.html" title="项目信息"><span class="icon-chevron-right"></span>项目信息</a></li>
    <li><a href="http://mybatis.org/spring/zh/project-reports.html" title="项目报表"><span class="icon-chevron-right"></span>项目报表</a></li>
</ul>
          <hr>
          <div id="poweredBy">
            <div class="clear"></div>
            <div class="clear"></div>
            <div class="clear"></div>
            <div class="clear"></div>
<a href="http://maven.apache.org/" title="构建依靠 Maven" class="poweredBy"><img class="builtBy" alt="构建依靠 Maven" src="./mybatis-spring – MyBatis-Spring _ 使用 SqlSession_files/maven-feather.png"></a>
            </div>
          </div>
        </div>
        <div id="bodyColumn" class="span10">


  
    <div class="section">
<h2><a name="a.E4.BD.BF.E7.94.A8_SqlSession"></a>使用 SqlSession</h2>
      
<p>
        在 MyBatis 中，你可以使用 <tt>SqlSessionFactory</tt> 来创建 <tt>SqlSession</tt>。一旦你获得一个 session 之后，你可以使用它来执行映射了的语句，提交或回滚连接，最后，当不再需要它的时候，你可以关闭 session。使用 MyBatis-Spring 之后，你不再需要直接使用 <tt>SqlSessionFactory</tt> 了，因为你的 bean 可以被注入一个线程安全的 <tt>SqlSession</tt>，它能基于 Spring 的事务配置来自动提交、回滚、关闭 session。
      </p>  
    
    
<div class="section">
<h3><a name="SqlSessionTemplate"></a>SqlSessionTemplate</h3>
      
<p>
        <tt>SqlSessionTemplate</tt> 是 MyBatis-Spring 的核心。作为 <tt>SqlSession</tt> 的一个实现，这意味着可以使用它无缝代替你代码中已经在使用的 <tt>SqlSession</tt>。<tt>SqlSessionTemplate</tt> 是线程安全的，可以被多个 DAO 或映射器所共享使用。
      </p>

      
<p>
        当调用 SQL 方法时（包括由 <tt>getMapper()</tt> 方法返回的映射器中的方法），<tt>SqlSessionTemplate</tt> 将会保证使用的 <tt>SqlSession</tt> 与当前 Spring 的事务相关。此外，它管理 session 的生命周期，包含必要的关闭、提交或回滚操作。另外，它也负责将 MyBatis 的异常翻译成 Spring 中的 <tt>DataAccessExceptions</tt>。
      </p>

      
<p>
        由于模板可以参与到 Spring 的事务管理中，并且由于其是线程安全的，可以供多个映射器类使用，你应该<b>总是</b>用 <tt>SqlSessionTemplate</tt> 来替换 MyBatis 默认的 <tt>DefaultSqlSession</tt> 实现。在同一应用程序中的不同类之间混杂使用可能会引起数据一致性的问题。
      </p>

      
<p>
        可以使用 <tt>SqlSessionFactory</tt> 作为构造方法的参数来创建 <tt>SqlSessionTemplate</tt> 对象。
      </p>
        
<div class="source"><pre class="prettyprint"><span class="tag">&lt;bean</span><span class="pln"> </span><span class="atn">id</span><span class="pun">=</span><span class="atv">"sqlSession"</span><span class="pln"> </span><span class="atn">class</span><span class="pun">=</span><span class="atv">"org.mybatis.spring.SqlSessionTemplate"</span><span class="tag">&gt;</span><span class="pln">
  </span><span class="tag">&lt;constructor-arg</span><span class="pln"> </span><span class="atn">index</span><span class="pun">=</span><span class="atv">"0"</span><span class="pln"> </span><span class="atn">ref</span><span class="pun">=</span><span class="atv">"sqlSessionFactory"</span><span class="pln"> </span><span class="tag">/&gt;</span><span class="pln">
</span><span class="tag">&lt;/bean&gt;</span></pre></div>

      
<div class="source"><pre class="prettyprint"><span class="lit">@Bean</span><span class="pln">
</span><span class="kwd">public</span><span class="pln"> </span><span class="typ">SqlSessionTemplate</span><span class="pln"> sqlSession</span><span class="pun">()</span><span class="pln"> </span><span class="kwd">throws</span><span class="pln"> </span><span class="typ">Exception</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="kwd">return</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">SqlSessionTemplate</span><span class="pun">(</span><span class="pln">sqlSessionFactory</span><span class="pun">());</span><span class="pln">
</span><span class="pun">}</span></pre></div>

      
<p>
        现在，这个 bean 就可以直接注入到你的 DAO bean 中了。你需要在你的 bean 中添加一个 SqlSession 属性，就像下面这样：
      </p>
        
<div class="source"><pre class="prettyprint"><span class="kwd">public</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">UserDaoImpl</span><span class="pln"> </span><span class="kwd">implements</span><span class="pln"> </span><span class="typ">UserDao</span><span class="pln"> </span><span class="pun">{</span><span class="pln">

  </span><span class="kwd">private</span><span class="pln"> </span><span class="typ">SqlSession</span><span class="pln"> sqlSession</span><span class="pun">;</span><span class="pln">

  </span><span class="kwd">public</span><span class="pln"> </span><span class="kwd">void</span><span class="pln"> setSqlSession</span><span class="pun">(</span><span class="typ">SqlSession</span><span class="pln"> sqlSession</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">sqlSession </span><span class="pun">=</span><span class="pln"> sqlSession</span><span class="pun">;</span><span class="pln">
  </span><span class="pun">}</span><span class="pln">

  </span><span class="kwd">public</span><span class="pln"> </span><span class="typ">User</span><span class="pln"> getUser</span><span class="pun">(</span><span class="typ">String</span><span class="pln"> userId</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="kwd">return</span><span class="pln"> sqlSession</span><span class="pun">.</span><span class="pln">selectOne</span><span class="pun">(</span><span class="str">"org.mybatis.spring.sample.mapper.UserMapper.getUser"</span><span class="pun">,</span><span class="pln"> userId</span><span class="pun">);</span><span class="pln">
  </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></pre></div>
      
<p>
        按下面这样，注入 <tt>SqlSessionTemplate</tt>：
      </p>      
        
<div class="source"><pre class="prettyprint"><span class="tag">&lt;bean</span><span class="pln"> </span><span class="atn">id</span><span class="pun">=</span><span class="atv">"userDao"</span><span class="pln"> </span><span class="atn">class</span><span class="pun">=</span><span class="atv">"org.mybatis.spring.sample.dao.UserDaoImpl"</span><span class="tag">&gt;</span><span class="pln">
  </span><span class="tag">&lt;property</span><span class="pln"> </span><span class="atn">name</span><span class="pun">=</span><span class="atv">"sqlSession"</span><span class="pln"> </span><span class="atn">ref</span><span class="pun">=</span><span class="atv">"sqlSession"</span><span class="pln"> </span><span class="tag">/&gt;</span><span class="pln">
</span><span class="tag">&lt;/bean&gt;</span></pre></div>

      
<p>
        <tt>SqlSessionTemplate</tt> 还有一个接收 <tt>ExecutorType</tt> 参数的构造方法。这允许你使用如下 Spring 配置来批量创建对象，例如批量创建一些 SqlSession：
      </p>
      
<div class="source"><pre class="prettyprint"><span class="tag">&lt;bean</span><span class="pln"> </span><span class="atn">id</span><span class="pun">=</span><span class="atv">"sqlSession"</span><span class="pln"> </span><span class="atn">class</span><span class="pun">=</span><span class="atv">"org.mybatis.spring.SqlSessionTemplate"</span><span class="tag">&gt;</span><span class="pln">
  </span><span class="tag">&lt;constructor-arg</span><span class="pln"> </span><span class="atn">index</span><span class="pun">=</span><span class="atv">"0"</span><span class="pln"> </span><span class="atn">ref</span><span class="pun">=</span><span class="atv">"sqlSessionFactory"</span><span class="pln"> </span><span class="tag">/&gt;</span><span class="pln">
  </span><span class="tag">&lt;constructor-arg</span><span class="pln"> </span><span class="atn">index</span><span class="pun">=</span><span class="atv">"1"</span><span class="pln"> </span><span class="atn">value</span><span class="pun">=</span><span class="atv">"BATCH"</span><span class="pln"> </span><span class="tag">/&gt;</span><span class="pln">
</span><span class="tag">&lt;/bean&gt;</span></pre></div>

      
<div class="source"><pre class="prettyprint"><span class="lit">@Bean</span><span class="pln">
</span><span class="kwd">public</span><span class="pln"> </span><span class="typ">SqlSessionTemplate</span><span class="pln"> sqlSession</span><span class="pun">()</span><span class="pln"> </span><span class="kwd">throws</span><span class="pln"> </span><span class="typ">Exception</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="kwd">return</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">SqlSessionTemplate</span><span class="pun">(</span><span class="pln">sqlSessionFactory</span><span class="pun">(),</span><span class="pln"> </span><span class="typ">ExecutorType</span><span class="pun">.</span><span class="pln">BATCH</span><span class="pun">);</span><span class="pln">
</span><span class="pun">}</span></pre></div>

      
<p>
        现在所有的映射语句可以进行批量操作了，可以在 DAO 中编写如下的代码
      </p>
        
<div class="source"><pre class="prettyprint"><span class="kwd">public</span><span class="pln"> </span><span class="kwd">void</span><span class="pln"> insertUsers</span><span class="pun">(</span><span class="typ">List</span><span class="pun">&lt;</span><span class="typ">User</span><span class="pun">&gt;</span><span class="pln"> users</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="kwd">for</span><span class="pln"> </span><span class="pun">(</span><span class="typ">User</span><span class="pln"> user </span><span class="pun">:</span><span class="pln"> users</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    sqlSession</span><span class="pun">.</span><span class="pln">insert</span><span class="pun">(</span><span class="str">"org.mybatis.spring.sample.mapper.UserMapper.insertUser"</span><span class="pun">,</span><span class="pln"> user</span><span class="pun">);</span><span class="pln">
  </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></pre></div>
  
      
<p>
        注意，只需要在希望语句执行的方法与 <tt>SqlSessionTemplate</tt> 中的默认设置不同时使用这种配置。
      </p>

      
<p>
        这种配置的弊端在于，当调用这个方法时，不能存在使用不同 <tt>ExecutorType</tt> 的进行中的事务。要么确保对不同 <tt>ExecutorType</tt> 的 <tt>SqlSessionTemplate</tt> 的调用处在不同的事务中，要么完全不使用事务。
      </p>
    </div>

    
<div class="section">
<h3><a name="SqlSessionDaoSupport"></a>SqlSessionDaoSupport</h3>
      
<p>
        <tt>SqlSessionDaoSupport</tt> 是一个抽象的支持类，用来为你提供 <tt>SqlSession</tt>。调用 <tt>getSqlSession()</tt> 方法你会得到一个 <tt>SqlSessionTemplate</tt>，之后可以用于执行 SQL 方法，就像下面这样:
      </p>
        
<div class="source"><pre class="prettyprint"><span class="kwd">public</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">UserDaoImpl</span><span class="pln"> </span><span class="kwd">extends</span><span class="pln"> </span><span class="typ">SqlSessionDaoSupport</span><span class="pln"> </span><span class="kwd">implements</span><span class="pln"> </span><span class="typ">UserDao</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="kwd">public</span><span class="pln"> </span><span class="typ">User</span><span class="pln"> getUser</span><span class="pun">(</span><span class="typ">String</span><span class="pln"> userId</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="kwd">return</span><span class="pln"> getSqlSession</span><span class="pun">().</span><span class="pln">selectOne</span><span class="pun">(</span><span class="str">"org.mybatis.spring.sample.mapper.UserMapper.getUser"</span><span class="pun">,</span><span class="pln"> userId</span><span class="pun">);</span><span class="pln">
  </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></pre></div>
      
<p>
        在这个类里面，通常更倾向于使用 <tt>MapperFactoryBean</tt>，因为它不需要额外的代码。但是，如果你需要在 DAO 中做其它非 MyBatis 的工作或需要一个非抽象的实现类，那么这个类就很有用了。
      </p>

      
<p>
        <tt>SqlSessionDaoSupport</tt> 需要通过属性设置一个 <tt>sqlSessionFactory</tt> 或 <tt>SqlSessionTemplate</tt>。如果两个属性都被设置了，那么 <tt>SqlSessionFactory</tt> 将被忽略。
      </p>

      
<p>
        假设类 <tt>UserMapperImpl</tt> 是 <tt>SqlSessionDaoSupport</tt> 的子类，可以编写如下的 Spring 配置来执行设置：
      </p>
      
<div class="source"><pre class="prettyprint"><span class="tag">&lt;bean</span><span class="pln"> </span><span class="atn">id</span><span class="pun">=</span><span class="atv">"userDao"</span><span class="pln"> </span><span class="atn">class</span><span class="pun">=</span><span class="atv">"org.mybatis.spring.sample.dao.UserDaoImpl"</span><span class="tag">&gt;</span><span class="pln">
  </span><span class="tag">&lt;property</span><span class="pln"> </span><span class="atn">name</span><span class="pun">=</span><span class="atv">"sqlSessionFactory"</span><span class="pln"> </span><span class="atn">ref</span><span class="pun">=</span><span class="atv">"sqlSessionFactory"</span><span class="pln"> </span><span class="tag">/&gt;</span><span class="pln">
</span><span class="tag">&lt;/bean&gt;</span></pre></div>
      </div>
    </div>
  

        </div>
      </div>
    </div>
    <hr>
    <footer>
      <div class="container-fluid">
        <div class="row-fluid">
            <p>Copyright ©2010–2020
<a href="http://www.mybatis.org/">MyBatis.org</a>.
All rights reserved.</p>
        </div>
      </div>
    </footer>
  

<div class="xl-chrome-ext-bar" id="xl_chrome_ext_{4DB361DE-01F7-4376-B494-639E489D19ED}" style="display: none;">
      <div class="xl-chrome-ext-bar__logo"></div>

      <a id="xl_chrome_ext_download" href="javascript:;" class="xl-chrome-ext-bar__option">下载视频</a>
      <a id="xl_chrome_ext_close" href="javascript:;" class="xl-chrome-ext-bar__close"></a>
    </div></body></html>